package com.ctshk.common.utils;

import com.alibaba.nacos.common.http.param.MediaType;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.client.utils.URLEncodedUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.*;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.util.CollectionUtils;

import java.io.*;
import java.net.*;
import java.util.*;

public class HttpUtils {

    public static <T> T httpRequest(HttpUriRequest request, ResponseHandler<T> handler) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        try {
            return httpclient.execute(request, handler);
        } catch (Exception ex) {
            return null;
        } finally {
            HttpClientUtils.closeQuietly(httpclient);
        }
    }

    public static <T> T getRequest(URI uri, ResponseHandler<T> handler) {

        return httpRequest(new HttpGet(uri), handler);
    }

    public static <T> T postRequest(String url, String body, Map<String, String> header, ResponseHandler<T> handler) throws Exception {
        HttpPost httpPost = new HttpPost(url);
        if (!CollectionUtils.isEmpty(header)) {
            header.forEach(httpPost::addHeader);
        }
        if (StringUtils.isNotBlank(body)) {
            StringEntity stringEntity = new StringEntity(body);
            stringEntity.setContentType(header.get("Content-Type"));
            httpPost.setEntity(stringEntity);
        }
        return httpRequest(httpPost, handler);
    }


    /**
     * 中汽巴士接口公共接口方法
     *
     * @param urlStr
     * @param xmlInfo
     * @return
     */
    public static String xmlSendByPost(String urlStr, String xmlInfo) {
        try {
            URL url = new URL(urlStr);
            URLConnection con = url.openConnection();
            con.setDoOutput(true);
            // 一定要设置报文格式，否则发送失败
            con.setRequestProperty("Content-Type", "text/xml;charset=UTF-8");

            OutputStreamWriter out = null;
            try {
                out = new OutputStreamWriter(con.getOutputStream());
            } catch (ConnectException e) {
                return "Connection refused";
            }
            out.write(new String(xmlInfo.getBytes("UTF-8")));
            out.flush();
            out.close();
            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
            StringBuilder stringBuilder = new StringBuilder();
            String line = "";
            for (line = br.readLine(); line != null; line = br.readLine()) {
                stringBuilder.append(line);
            }
            return stringBuilder.toString();
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 中港通巴士接口公共方法
     *
     * @param url      httpurl
     * @param paramMap 参数  key参数名，value参数值
     * @return 返回请求体
     * @throws IOException
     */
    public static String httpget(String url, Map<String, String> paramMap) {
        try {
            HttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet();
            List<NameValuePair> formparams = new ArrayList<NameValuePair>();
            Set<Map.Entry<String, String>> set = paramMap.entrySet();
            for (Map.Entry<String, String> entry : set) {
                formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            String param = URLEncodedUtils.format(formparams, "UTF-8");
            httpGet.setURI(URI.create(url + "?" + param));
            HttpResponse httpResponse = httpClient.execute(httpGet);
            String responseStr = getResponseStr(httpResponse);
            httpGet.abort();
            return responseStr;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    private static String getResponseStr(HttpResponse response) throws IOException {
        HttpEntity entity = response.getEntity();
        if (entity != null) {
            InputStream is = entity.getContent();
            BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
            String line = br.readLine();
            StringBuilder sb = new StringBuilder();
            while (line != null) {
                sb.append(line + "\n");
                line = br.readLine();
            }
            br.close();
            is.close();
            return sb.toString();
        }
        return "";
    }

    /**
     * 发送https，post请求
     *
     * @param url
     * @param bodyStr
     * @return
     * @throws Exception
     */
    public static String sendHttpSslPost(String url, String bodyStr) throws Exception {
        // 创建httpPost远程连接实例
        HttpPost post = new HttpPost(url);
        String result = "";
        try {
            HttpEntity entity = new StringEntity(bodyStr, "UTF-8");
            post.setEntity(entity);
            post.setHeader("Content-type", "application/json");
            HttpSSLClient httpSslClient = new HttpSSLClient();
            HttpResponse response = httpSslClient.execute(post);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, "UTF-8");
                }
            }
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    public static String sendHttpSslGet(String url, HashMap<String, String> paramMap) throws Exception {
        // 创建httpPost远程连接实例
        String result = "";
        try {
            String paramStr = com.alibaba.nacos.common.http.HttpUtils.encodingParams(paramMap, "UTF-8");
            url = url + "?" +paramStr;
            HttpGet get = new HttpGet(url);
            get.setHeader("Content-type", "application/json");
            HttpSSLClient httpSslClient = new HttpSSLClient();
            HttpResponse response = httpSslClient.execute(get);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, "UTF-8");
                }
            }
            return result;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 中港通巴士接口公共方法
     *
     * @param url      httpurl
     * @param paramMap 参数  key参数名，value参数值
     * @return 返回请求体
     * @throws IOException
     */
    public static String sendHttpGet(String url, Map<String, String> paramMap) {
        try {
            HttpClient httpClient = new DefaultHttpClient();
            HttpGet httpGet = new HttpGet();
            List<NameValuePair> formparams = new ArrayList<NameValuePair>();
            Set<Map.Entry<String, String>> set = paramMap.entrySet();
            for (Map.Entry<String, String> entry : set) {
                formparams.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
            }
            String param = URLEncodedUtils.format(formparams, "UTF-8");
            httpGet.setURI(URI.create(url + "?" + param));
            HttpResponse httpResponse = httpClient.execute(httpGet);
            String responseStr = getResponseStr(httpResponse);
            httpGet.abort();
            return responseStr;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String doPost(String url, Map paramMap) {
        return doPostHttp(url, paramMap, MediaType.APPLICATION_JSON);
    }

    public static String doPost(String url, Map paramMap, String mediaType) {
        return doPostHttp(url, paramMap, mediaType);
    }

    private static String doPostHttp(String url, Map paramMap, String mediaType) {
        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        String result = "";
        // 创建httpClient实例
        httpClient = HttpClients.createDefault();
        // 创建httpPost远程连接实例
        HttpPost httpPost = new HttpPost(url);
        // 配置请求参数实例
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(35000)// 设置连接主机服务超时时间
                .setConnectionRequestTimeout(35000)// 设置连接请求超时时间
                .setSocketTimeout(60000)// 设置读取数据连接超时时间
                .build();
        // 为httpPost实例设置配置
        httpPost.setConfig(requestConfig);
        // 设置请求头
        httpPost.addHeader("Content-Type", mediaType);
        // 封装post请求参数
        try {
            if (null != paramMap && paramMap.size() > 0) {
                List<NameValuePair> nvps = new ArrayList<NameValuePair>();
                // 通过map集成entrySet方法获取entity
                Set<Map.Entry> entrySet = paramMap.entrySet();
                // 循环遍历，获取迭代器
                Iterator<Map.Entry> iterator = entrySet.iterator();
                while (iterator.hasNext()) {
                    Map.Entry mapEntry = iterator.next();
                    nvps.add(new BasicNameValuePair(mapEntry.getKey().toString(), mapEntry.getValue().toString()));
                }
                // 为httpPost设置封装好的请求参数
                httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
            }
            // httpClient对象执行post请求,并返回响应参数对象
            httpResponse = httpClient.execute(httpPost);
            // 从响应对象中获取响应内容
            HttpEntity entity = httpResponse.getEntity();
            result = EntityUtils.toString(entity);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != httpResponse) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    /**
     * UrlEncodedFormEntity 转换成 Form表单提交
     *
     * @param url       提交地址
     * @param paramsMap 提交map参数
     * @return
     */
    public static String post(String url, Map<String, String> paramsMap) {
        CloseableHttpClient client = HttpClients.createDefault();
        HttpClient clientRedirect = HttpClientBuilder.create().setRedirectStrategy(new LaxRedirectStrategy()).build();

        String responseText = "";
        HttpResponse responseRe = null;
        CloseableHttpResponse response = null;
        try {
            HttpPost method = new HttpPost(url);
            if (paramsMap != null) {
                List<NameValuePair> paramList = new ArrayList<NameValuePair>();
                for (Map.Entry<String, String> param : paramsMap.entrySet()) {
                    NameValuePair pair = new BasicNameValuePair(param.getKey(), param.getValue());
                    paramList.add(pair);
                }
                method.setEntity(new UrlEncodedFormEntity(paramList, "UTF-8"));
            }
            responseRe = clientRedirect.execute(method);
//            response = client.execute(method);
            if (responseRe.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
                // 返回数据：
                Header[] locals = responseRe.getHeaders("Local");
                responseText = EntityUtils.toString(responseRe.getEntity(), "UTF-8");
                System.out.println("===>" + responseText);
            } else {
                throw new RuntimeException("接口连接失败！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                response.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return responseText;
    }
}
